/* $Header: sig_util.c,v 2.2 01/10/02 10:33:06 przybyls Exp $ */

/***********************************************************************/
/*                                                                     */
/*                  Copyright Hewlett-Packard Co. 1991                 */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/* MODULE NAME: sig_util.c                                             */
/* ============                                                        */
/*                                                                     */
/* Author:  Lesley Freed                                               */
/*                                                                     */
/* MODULE PURPOSE:  To provide utility functions for the signal path.  */
/*                                                                     */
/***********************************************************************/

/*****************************/
/*   GLOBAL INCLUDE FILES    */
/*****************************/

#include <typedefs.h>
#include <p_wkfile.h>
#include <wkfile.h>
#include <ramps.h>
#include <zone_config.h>
#include <i_op.h>
#include <zone_status.h>
#include <status.h>
#include <error.h>
#include <sig_types.h>
#include <sig_ui.h>
#include <sigpath.h>
#include <math.h>

/*****************************/
/*   LOCAL INCLUDE FILES     */
/*****************************/


/*****************************/
/*   GLOBAL VARIABLES        */
/*****************************/

   SIG_FILTER Sig1_Filt;
   SIG_FILTER Sig2_Filt;
   SIG_FILTER Deta_Filt;
   SIG_FILTER Detb_Filt;
   INT32 Sig1_Filt_Table[ARRAY_SIZE_SIG_DISP];
   INT32 Sig2_Filt_Table[ARRAY_SIZE_SIG_DISP];
   INT32 Deta_Filt_Table[ARRAY_SIZE_SCC_DET];
   INT32 Detb_Filt_Table[ARRAY_SIZE_SCC_DET];

/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/


/*****************************/
/*   LOCAL DEFINES           */
/*****************************/




/*****************************/
/*   IMPLEMENT SECTION       */
/*****************************/

INT32 ConvertToMv( INT32 value, pPLOT_CONSTANTS pconstants )
{
   /* subtract the offset */
   value -= pconstants->offset;

   /* scale the signal */
   value = SignedQuadWordMultiplyDivide( value,
                                         pconstants->multiplier,
                                         pconstants->divisor );

   return( value/SIG_DISP_SCALE_FACTOR );
}

/***********************************************************************/
/* FUNCTION:  ConvertPlotValueToSignalUnits                            */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  To convert an alternate type signal from its internal     */
/*           units to the fundamental units.                           */
/*                                                                     */
/* RETURNED VALUE:  none                                               */
/*                                                                     */
/* GLOBALS USED:  Signal1, Signal2                                     */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

void ConvertPlotValue( pSIG_TABLE psignal )
{
   INT32       s_signal;
   pSIG_FILTER pfilt;

   /* Only convert if the signal is an alternate signal */
   if( psignal->plot_size != NOT_PLOT_SIGNAL )
   {

      /* First get the signal */

      INTERRUPTS_OFF

      switch ( psignal->plot_size )
      {
         case SIZE_32_BIT:
            s_signal = *(U_INT32*)psignal->plot;
            break;

         case SIZE_16_BIT:
            s_signal = *(U_INT16*)psignal->plot;
            break;

         case SIZE_8_BIT:
            s_signal = *(U_INT8*)psignal->plot;
            break;

         case SIZE_16_BIT_SIGNED:
            s_signal = *(INT16*)psignal->plot;
            break;

         case SIZE_8_BIT_SIGNED:
         default:
            s_signal = *(INT8*)psignal->plot;
            break;

      }

      INTERRUPTS_ON

      /* First see if we have a nasty, noisy signal that needs filtering,sigh.*/
      if ( psignal == &Signal1 )
      {
         pfilt = &Sig1_Filt;
      }
      else
      {
         pfilt = &Sig2_Filt;
      }

      switch( psignal->signal )
      {
         case ATTN1_SIGNAL:
         case ATTN2_SIGNAL:
         case DAC1_SIGNAL:
         case DAC2_SIGNAL:
         case DET_DIAGA_SIGNAL:
         case DET_DIAGB_SIGNAL:
         case DET_DIAGC_SIGNAL:
         case DET_DIAGD_SIGNAL:
            FilterSignal32( pfilt, s_signal, ARRAY_SIZE_SIG_DISP );
            s_signal = pfilt->filt_out.output;
            break;

         default:
            break;
      }

      if ( ScaledSignal( psignal ) )
      {
         /* subtract the offset */
         s_signal -= psignal->pconstants->offset;

         /* scale the signal */
         s_signal = SignedQuadWordMultiplyDivide( s_signal,
                                               psignal->pconstants->multiplier,
                                               psignal->pconstants->divisor );
      }

      psignal->plot_out = s_signal;
   }
}

void ConvertPlotValueToSignalUnits( void )
{
   ConvertPlotValue( pSIGNAL1 );
   ConvertPlotValue( pSIGNAL2 );
   ConvertPlotValue( pSIGNALP );
}

INT32 GetSignalFromSizeAndAddr( DATA_SIZE size, U_INT32 *addr )
{
   switch ( size )
   {
      case SIZE_32_BIT:
         return *(U_INT32*)addr;

      case SIZE_16_BIT:
         return *(U_INT16*)addr;

      case SIZE_8_BIT:
         return *(U_INT8*)addr;

      case SIZE_16_BIT_SIGNED:
         return *(INT16*)addr;

      case SIZE_8_BIT_SIGNED:
      default:
         return *(INT8*)addr;
   }
}


INT32 GetSignalNoise( pSIG_TABLE psignal )
{
      return ( psignal->noise);
}



#pragma SECTION PROG=SysCode

void FilterSignal32( pSIG_FILTER pfilt, INT32 s_signal, U_INT16 size )
{
   pfilt->filt_sum = FiltSum(s_signal,
                             pfilt->pfilt_table[ pfilt->ptr_filt],
                             pfilt->filt_sum.hi,pfilt->filt_sum.lo);

   /* Store the new data point in the array */
   pfilt->pfilt_table[ pfilt->ptr_filt ] = s_signal;

   pfilt->filt_out = BunchOut32(pfilt->filt_sum.hi,
                                pfilt->filt_sum.lo,
                                size,
                                pfilt->filt_out.remainder);

   /* Update the filter array pointer to point to the new oldest */
   /*  data point.  If the pointer is to the top of the array    */
   /*  put it down to the bottom of the array which is actually  */
   /*  a circular buffer, otherwise move it up one position.     */

   if ( pfilt->ptr_filt  )
   {
      pfilt->ptr_filt--;
   }
   else
   {
      pfilt->ptr_filt = size-1;
   }
}

/***********************************************************************/
/* FUNCTION:  SetSigpathStopMarkers                                    */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  To set the stop markers for the signal path.              */
/*                                                                     */
/* RETURNED VALUE:  none                                               */
/*                                                                     */
/* GLOBALS USED:  Signal1, Signal2                                     */
/*                                                                     */
/* CALLS:  none                                                        */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

void SetSigpathStopMarkers( void )
{
   /* Set a flag for each signal indicating that a stop has occurred */
   Signal1.stop_run_marker = TRUE;
   Signal2.stop_run_marker = TRUE;

}

#pragma SECTION UNDO
